package worker

import (
	"context"
	"errors"
	"fmt"
	"strings"
	"time"

	"zhonghui/console/service"
	"zhonghui/console/structs"
	"zhonghui/console/warehouse/dbx"
	"zhonghui/console/warehouse/dbx/cache_main"
	"zhonghui/console/warehouse/dbx/db_zh_kernel"
	"zhonghui/console/warehouse/logx"
	"zhonghui/console/warehouse/modelx/model_zh_kernel"
)

// TaskScanWorkerJD 检测进行中的任务，发送短信的MQ
type TaskScanWorkerJD struct {
	S, Q int
}
type run2 struct {
	TaskID     uint64
	UseDwz     uint
	RecordID   uint64
	LocalDwz   string
	Dwz        string
	TemplateId string
}

func (w *TaskScanWorkerJD) Start(s, q int) {
	w.S = s
	w.Q = q
	w.do()
	t := time.NewTicker(1 * time.Second)
	for {
		select {
		case <-t.C:
			w.do()
		}
	}
}

func (w *TaskScanWorkerJD) do() {
	defer func() {
		if r := recover(); r != nil {
			logx.Zap().Errorw("定时任务异常", "err", errors.New(fmt.Sprintf("%s", r)))
		}
	}()

	rc := cache_main.Client()
	lock, ch, err := dbx.GetRedisLockWithRefresh(rc, dbx.RedisPrefix(fmt.Sprintf("locker-TaskScanWorkerJD-%d-%d", w.S, w.Q)), 5*time.Second, time.Second)
	if err != nil {
		return
	}
	defer func() {
		if ch != nil {
			ch <- 1
		}
		_ = lock.Release(context.Background())
	}()

	// 生成mq，更新数据
	mqs := w.mqs(w.list())
	if len(mqs) == 0 {
		return
	}

	// 休息一会
	time.Sleep(1 * time.Second)

	// 触发短信发送任务
	if err := service.TriggerSmsSendTaskMulti(mqs); err != nil {
		logx.Zap().Errorw("触发短信发送任务失败", "err", err)
		return
	}
}

// 查询待发的短信列表
func (w *TaskScanWorkerJD) list() []run2 {
	list := make([]run2, 0)
	db_zh_kernel.Client().Table("sys_task as t").
		Joins("join sys_sms_record as tr on tr.task_id = t.id").
		Where("t.status = ? and t.sms_template like 'JD_%'", structs.TaskStatusProcessing).
		Where("tr.status = ''").
		Where("tr.id % ? = ?", w.S, w.Q).
		Select("t.id as task_id, t.use_dwz, tr.id as record_id, t.sms_template as template_id").
		Order("tr.id asc").
		Limit(1000).
		Find(&list)

	p := "p4"

	// 生成短网址
	localDwzList := make([]string, 0)
	for i, item := range list {
		localDwz := service.GenLocalSmsUrl(item.RecordID, "", p)
		if item.UseDwz == 1 {
			localDwzList = append(localDwzList, localDwz)
		} else {
			localDwzList = append(localDwzList, "NONE_"+localDwz)
		}
		list[i].LocalDwz = localDwz
	}

	// 匹配长短网址，赋值
	dwzList := service.GenZhDwzBatch(localDwzList)
	if len(dwzList) == 0 {
		return nil
	}

	for i, item := range list {
		for _, d := range dwzList {
			if d.LongUrl == item.LocalDwz {
				list[i].Dwz = strings.TrimPrefix(d.ShortUrl, "https://")
				break
			}
		}
	}

	return list
}

// 循环拼接mq，更新状态
func (w *TaskScanWorkerJD) mqs(list []run2) []structs.SmsSendWorkerBody {
	conn := dbx.NewTx(db_zh_kernel.Client())
	defer conn.End()

	mqs := make([]structs.SmsSendWorkerBody, 0)
	for _, item := range list {
		if item.Dwz == "" {
			conn.Tx.Model(model_zh_kernel.SysSmsRecord{}).Where("id = ? and status = ''", item.RecordID).Updates(map[string]interface{}{
				"status": "fail",
			})
			continue
		}

		up := conn.Tx.Model(model_zh_kernel.SysSmsRecord{}).Where("id = ? and status = ''", item.RecordID).Updates(map[string]interface{}{
			"status": "queue",
			"dwz":    item.Dwz,
			"remark": item.LocalDwz,
		})
		if up.Error != nil {
			logx.Zap().Errorw("更新入队消息失败", "err", up.Error)
			continue
		}
		if up.RowsAffected != 1 {
			logx.Zap().Errorw("更新入队消息失败", "err", errors.New("affected rows is not 1"))
			continue
		}

		mqs = append(mqs, structs.SmsSendWorkerBody{
			TaskID:   item.TaskID,
			RecordID: item.RecordID,
		})
	}

	conn.Commit()

	return mqs
}
